namespace MTOM_Library
{
    using MTOM_Library.MtomWebService;
    using System;
    using System.ComponentModel;
    using System.IO;
    using System.Net;
    using System.Runtime.CompilerServices;
    using System.Security.Cryptography;
    using System.Threading;

    public class FileTransferBase : BackgroundWorker
    {
        public bool AutoSetChunkSize = true;
        public int ChunkSize = 0x4000;
        public int ChunkSizeSampleInterval = 15;
        private CookieContainer cookies = new CookieContainer();
        public string Guid;
        protected Thread HashThread;
        public bool IncludeHashVerification = true;
        public string LocalFileHash;
        protected string LocalFileName;
        public string LocalFilePath;
        public long MaxRequestLength = 0x1000L;
        public int MaxRetries = 50;
        protected int NumRetries = 0;
        protected long Offset = 0L;
        public int PreferredTransferDuration = 800;
        public string RemoteFileHash;
        protected DateTime StartTime;
        public string UpType;
        protected MTOMWse ws;

        public event EventHandler ChunkSizeChanged;

        public FileTransferBase()
        {
            base.WorkerReportsProgress = true;
            base.WorkerSupportsCancellation = true;
        }

        protected void CalcAndSetChunkSize()
        {
            double totalMilliseconds = DateTime.Now.Subtract(this.StartTime).TotalMilliseconds;
            double num2 = ((double) this.ChunkSize) / totalMilliseconds;
            double num3 = num2 * this.PreferredTransferDuration;
            this.ChunkSize = (int) Math.Min((double) this.MaxRequestLength, Math.Max(4096.0, num3));
            string sender = string.Format("Chunk size: {0}{1}", CalcFileSize((long)this.ChunkSize), (this.ChunkSize == this.MaxRequestLength) ? " (max)" : "");
            if (this.ChunkSizeChanged != null)
            {
                this.ChunkSizeChanged(sender, EventArgs.Empty);
            }
        }

        public static string CalcFileHash(string FilePath)
        {
            byte[] buffer;
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            using (FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 0x1000))
            {
                buffer = provider.ComputeHash(stream);
            }
            return BitConverter.ToString(buffer);
        }

        public static string CalcFileSize(long numBytes)
        {
            string str = "";
            if (numBytes > 0x40000000L)
            {
                str = $"{((double) numBytes) / 1073741824.0:0.00} Gb";
            }
            else if (numBytes > 0x100000L)
            {
                str = $"{((double) numBytes) / 1048576.0:0.00} Mb";
            }
            else
            {
                str = $"{((double) numBytes) / 1024.0:0} Kb";
            }
            if (str == "0 Kb")
            {
                str = "1 Kb";
            }
            return str;
        }

        protected void CheckLocalFileHash()
        {
            this.LocalFileHash = CalcFileHash(this.LocalFilePath);
        }

        protected override void Dispose(bool disposing)
        {
            if ((this.HashThread != null) && this.HashThread.IsAlive)
            {
                this.HashThread.Abort();
            }
            base.Dispose(disposing);
        }

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            try
            {
                long maxRequestLength = this.WebService.GetMaxRequestLength();
                this.MaxRequestLength = Math.Max((long) 1L, (long) ((maxRequestLength * 0x400L) - 0x800L));
            }
            catch (Exception)
            {
                this.MaxRequestLength = 0xfa0L;
            }
            base.OnDoWork(e);
        }

        protected override void OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
        {
            if ((this.HashThread != null) && this.HashThread.IsAlive)
            {
                this.HashThread.Abort();
            }
            base.OnRunWorkerCompleted(e);
        }

        public MTOMWse WebService
        {
            get
            {
                if (this.ws == null)
                {
                    this.ws = new MTOMWse();
                    this.ws.Credentials = CredentialCache.DefaultCredentials;
                    this.ws.CookieContainer = this.cookies;
                }
                return this.ws;
            }
            set
            {
                this.ws = value;
            }
        }
    }
}

